home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
qex
/
qexcvsd
/
mxcom.c
< prev
next >
Wrap
Text File
|
1994-05-24
|
6KB
|
272 lines
/* MXCOM.C -- Library functions for use with ARRL MX-COM MX709 codec card
*
* Used with Turbo C V2.0
*
* Copyright 1990, American Radio Relay League, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include "mxcom.h"
unsigned mxeint, mxdint, mxeover, mxdover;
unsigned int MXBASE = 0x300;
static char IRQ = 2;
static struct mxcom
{
char *flag;
struct mxbuf *buf[2];
unsigned cnt;
int bufnum;
} encode, decode;
static void interrupt (*oldvect)() = NULL;
/* Local functions to set/reset IRQ vector */
/* r e s t i r q
*/
static void
restirq(void)
{
disable();
outportb(0x21, inportb(0x21) | (1 << IRQ));
enable();
if (oldvect != NULL)
{
setvect(IRQ+8, oldvect);
oldvect = NULL;
}
}
/* s e t i r q
*/
static void
setirq(void interrupt (*svc)())
{
if (oldvect == NULL)
oldvect = getvect(IRQ+8);
setvect(IRQ+8, svc);
}
/* m x c a r d
*
* Set card hardware parameters
*
* base = base address of card (default = 0x300)
* irq = hardware interrupt number (default = 2)
*/
void
mxcard(unsigned base, char irq)
{
MXBASE = base;
IRQ = irq & 7;
}
/* m x i n i t
*
* Initialize instruction registers of MX709
*
* dsource = decoder data source select: IDLE|ENCODER
* esource = encoder audio input source: IDLE|CHANA|CHANB
* aout = channel A output source: DECODER|THROUGH
* bout = channel B output source: DECODER|THROUGH
* rate = codec rate: 0-7
* pagesize= power measurement page size: 0-7
* sens = power measurement sensitivity: LOW|HIGH
*
* Notes:
* 1. The codec rate in bit/s and the filter cut-off in Hz,
* both of which are selected by "rate" depend on the
* frequency of the clock (xtal) source.
*
* 2. For both "aout" and "bout" the THROUGH state connects
* the A or B input, respectively, to the output.
*
* 3. "pagesize" selects page sizes as follows:
* 0: 32 4: 160
* 1: 64 5: 192
* 2: 96 6: 224
* 3: 128 7: 256
*
* 4. No error checking is done on passed parameters.
*/
void
mxinit(char dsource, char esource, char aout, char bout, char rate,
char pagesize, char sens)
{
char insta = 0, instb = 0;
char c;
if (dsource == ENCODER)
insta |= 2;
if (esource)
{
if (esource == CHANB)
instb |= 8;
} else
insta |= 1;
if (aout == THROUGH)
instb |= 0x10;
if (bout == DECODER)
instb |= 0x20;
c = rate & 7;
insta |= (c << 5) | (c << 2);
instb |= pagesize & 7;
if (sens == HIGH)
instb |= 0x80;
outportb(MX_A, insta);
outportb(MX_B, instb);
}
/* m x r e s e t
*
* Reset card and interrupt system
*/
void
mxreset(void)
{
outportb(MX_A, 0);
outportb(MX_B, 0);
restirq();
}
/* m y s v c
*
* Local function to service interrupts
*
*/
static void interrupt
mysvc(void)
{
char c;
struct mxbuf *mxb;
c = inportb(MX_STAT);
if (c & 9) /* Encoder interrupt */
{
mxb = encode.buf[encode.bufnum];
if (mxb != NULL)
{
if (c & 8)
mxeover++;
mxb->dat[encode.cnt++] = inportb(MX_ENC);
mxeint = encode.cnt;
if (encode.cnt >= mxb->n)
{
*(encode.flag) = encode.bufnum + 1;
encode.bufnum = encode.bufnum ^ 1;
encode.cnt = 0;
}
}
}
if (c & 0x12) /* Decoder interrupt */
{
mxb = decode.buf[decode.bufnum];
if (mxb != NULL)
{
if (c & 0x10)
mxdover++;
outportb(MX_DEC, mxb->dat[decode.cnt++]);
mxdint = decode.cnt;
if (decode.cnt >= mxb->n)
{
*(decode.flag) = decode.bufnum + 1;
decode.bufnum = decode.bufnum ^ 1;
decode.cnt = 0;
}
}
}
outportb(0x20, 0x20);
}
/* m x _ e n c o d e
*
* Encode audio input and place data in memory. When called,
* mx_encode initiates the encoding process and then returns.
* The calling process must monitor the state of the eobflag byte
* to determine when the encoding is complete. One or two buffers
* may be used. If one buffer is used, encoding stops when the
* buffer is full. If two buffers are used. encoding continues
* filling alternate buffers until mx_stop is called.
*
* buf1 = pointer to first buffer struct
* buf2 = pointer to second buffer struct
* eobflag = pointer to flag byte
*
* Notes:
* 1. If buf2 == NULL, encoding will stop after filling buf1;
* If buf1 is NULL, no encoding will be performed.
*
* 2. The eobflag byte is written with a 1 when the last byte
* of buf1 has been filled and with a 2 when the last byte
* of buf2 has been filled. The calling program may
* change the contents of the eobflag byte at will.
*/
void
mx_encode(struct mxbuf *buf1, struct mxbuf *buf2, char *eobflag)
{
encode.buf[0] = buf1;
encode.buf[1] = buf2;
encode.flag = eobflag;
if (buf1 == NULL)
return;
encode.bufnum = 0;
mxeint = encode.cnt = 0;
*eobflag = 0;
setirq(mysvc);
disable();
inportb(MX_STAT);
inportb(MX_ENC);
outportb(0x21, inportb(0x21) & ~(1 << IRQ));
outportb(0x20, 0x20);
enable();
}
/* m x _ d e c o d e
*
* Sends data from memory to codec to be decoded into audio.
* mx_decode initiates the process and then returns. The calling
* process must monitor the state of the eobflag byte to
* determine when the decoding is complete.
*
* Arguments are the same as for the mx_encode function.
*/
void
mx_decode(struct mxbuf *buf1, struct mxbuf *buf2, char *eobflag)
{
decode.buf[0] = buf1;
decode.buf[1] = buf2;
decode.flag = eobflag;
if (buf1 == NULL)
return;
decode.bufnum = 0;
mxdint = decode.cnt = 1;
*eobflag = 0;
setirq(mysvc);
disable();
inportb(MX_STAT);
outportb(0x21, inportb(0x21) & ~(1 << IRQ));
outportb(0x20, 0x20);
outportb(MX_DEC, (decode.buf[0])->dat[0]);
enable();
}
/* m x s t o p
*
* Stop encoder or decoder
*
*/
void
mxstop(char side)
{
disable();
if (side == DECODER)
decode.buf[0] = decode.buf[1] = NULL;
else
encode.buf[0] = encode.buf[1] = NULL;
enable();
}